# ¿Cómo funcionan los Transformadores?

<CourseFloatingBanner
    chapter={1}
    classNames="absolute z-10 right-0 top-0"
/>

En esta sección, daremos una mirada de alto nivel a la arquitectura de los Transformadores.

## Un poco de historia sobre los Transformadores

Estos son algunos hitos en la (corta) historia de los Transformadores:

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_chrono.svg" alt="A brief chronology of Transformers models.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_chrono-dark.svg" alt="A brief chronology of Transformers models.">
</div>

La [arquitectura de los Transformadores](https://arxiv.org/abs/1706.03762) fue presentada por primera vez en junio de 2017. El trabajo original se enfocaba en tareas de traducción. A esto le siguió la introducción de numerosos modelos influyentes, que incluyen:

- **Junio de 2018**: [GPT](https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf), el primer modelo de Transformadores preentrenados, que fue usado para ajustar varias tareas de PLN y obtuvo resultados de vanguardia

- **Octubre de 2018**: [BERT](https://arxiv.org/abs/1810.04805), otro gran modelo preentrenado, diseñado para producir mejores resúmenes de oraciones (¡más sobre esto en el siguiente capítulo!)

- **Febrero de 2019**: [GPT-2](https://cdn.openai.com/better-language-models/language_models_are_unsupervised_multitask_learners.pdf), una versión mejorada (y más grande) de GPT, que no se liberó inmediatamente al público por consideraciones éticas

- **Octubre de 2019**: [DistilBERT](https://arxiv.org/abs/1910.01108), una versión destilada de BERT que es 60% más rápida, 40% más ligera en memoria y que retiene el 97% del desempeño de BERT

- **Octubre de 2019**: [BART](https://arxiv.org/abs/1910.13461) y [T5](https://arxiv.org/abs/1910.10683), dos grandes modelos preentrenados usando la misma arquitectura del modelo original de Transformador (los primeros en hacerlo)

- **Mayo de 2020**, [GPT-3](https://arxiv.org/abs/2005.14165), una versión aún más grande de GPT-2 con buen desempeño en una gran variedad de tareas sin la necesidad de ajustes (llamado _zero-shot learning_)

Esta lista está lejos de ser exhaustiva y solo pretende resaltar algunos de los diferentes modelos de Transformadores. De manera general, estos pueden agruparse en tres categorías:
- Parecidos a GPT (también llamados modelos _auto-regressive_)
- Parecidos a BERT (también llamados modelos _auto-encoding_)
- Parecidos a BART/T5 (también llamados modelos _sequence-to-sequence_)

Vamos a entrar en estas familias de modelos a profundidad más adelante.

## Los Transformadores son modelos de lenguaje

Todos los modelos de Transformadores mencionados con anterioridad (GPT, BERT, BART, T5, etc.) han sido entrenados como *modelos de lenguaje*. Esto significa que han sido entrenados con grandes cantidades de texto crudo de una manera auto-supervisada. El aprendizaje auto-supervisado es un tipo de entrenamiento en el que el objetivo se computa automáticamente de las entradas del modelo. ¡Esto significa que no necesitan humanos que etiqueten los datos!

Este tipo de modelos desarrolla un entendimiento estadístico del lenguaje sobre el que fue entrenado, pero no es muy útil para tareas prácticas específicas. Por lo anterior, el modelo general preentrenado pasa por un proceso llamado *transferencia de aprendizaje* (o *transfer learning* en Inglés). Durante este proceso, el modelo se ajusta de una forma supervisada -- esto es, usando etiquetas hechas por humanos -- para una tarea dada.

Un ejemplo de una tarea es predecir la palabra siguiente en una oración con base en las *n* palabras previas. Esto se denomina *modelado de lenguaje causal* porque la salida depende de las entradas pasadas y presentes, pero no en las futuras.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/causal_modeling.svg" alt="Example of causal language modeling in which the next word from a sentence is predicted.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/causal_modeling-dark.svg" alt="Example of causal language modeling in which the next word from a sentence is predicted.">
</div>

Otro ejemplo es el *modelado de lenguaje oculto*, en el que el modelo predice una palabra oculta en la oración.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/masked_modeling.svg" alt="Example of masked language modeling in which a masked word from a sentence is predicted.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/masked_modeling-dark.svg" alt="Example of masked language modeling in which a masked word from a sentence is predicted.">
</div>

## Los Transformadores son modelos grandes

Excepto algunos casos atípicos (como DistilBERT), la estrategia general para mejorar el desempeño es incrementar el tamaño de los modelos, así como la cantidad de datos con los que están preentrenados.

<div class="flex justify-center">
<img src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/model_parameters.png" alt="Number of parameters of recent Transformers models" width="90%">
</div>

Desafortunadamente, entrenar un modelo, especialmente uno grande, requiere de grandes cantidades de datos. Esto se vuelve muy costoso en términos de tiempo y recursos de computación, que se traduce incluso en impacto ambiental, como se puede ver en la siguiente gráfica.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/carbon_footprint.svg" alt="The carbon footprint of a large language model.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/carbon_footprint-dark.svg" alt="The carbon footprint of a large language model.">
</div>

<Youtube id="ftWlj4FBHTg"/>

Esto es ilustrativo para un proyecto que busca un modelo (muy grande), liderado por un equipo que intenta de manera consciente reducir el impacto ambiental del preentrenamiento. La huella de ejecutar muchas pruebas para encontrar los mejores hiperparámetros es aún mayor.

Ahora imagínate si cada vez que un equipo de investigación, una organización estudiantil o una compañía intentaran entrenar un modelo, tuvieran que hacerlo desde cero. ¡Esto implicaría costos globales enormes e innecesarios!

Esta es la razón por la que compartir modelos de lenguaje es fundamental: compartir los pesos entrenados y construir sobre los existentes reduce el costo general y la huella de carbono de la comunidad.

## Transferencia de aprendizaje (*Transfer learning*)

<Youtube id="BqqfQnyjmgg" />

El *preentrenamiento* es el acto de entrenar un modelo desde cero: los pesos se inicializan de manera aleatoria y el entrenamiento empieza sin un conocimiento previo.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/pretraining.svg" alt="The pretraining of a language model is costly in both time and money.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/pretraining-dark.svg" alt="The pretraining of a language model is costly in both time and money.">
</div>

Este preentrenamiento se hace usualmente sobre grandes cantidades de datos. Por lo anterior, requiere un gran corpus de datos y el entrenamiento puede tomar varias semanas.

Por su parte, el ajuste (o *fine-tuning*) es el entrenamiento realizado **después** de que el modelo ha sido preentrenado. Para hacer el ajuste, comienzas con un modelo de lenguaje preentrenado y luego realizas un aprendizaje adicional con un conjunto de datos específicos para tu tarea. Pero entonces -- ¿por qué no entrenar directamente para la tarea final? Hay un par de razones:

* El modelo preentrenado ya está entrenado con un conjunto de datos parecido al conjunto de datos de ajuste. De esta manera, el proceso de ajuste puede hacer uso del conocimiento adquirido por el modelo inicial durante el preentrenamiento (por ejemplo, para problemas de PLN, el modelo preentrenado tendrá algún tipo de entendimiento estadístico del idioma que estás usando para tu tarea).
* Dado que el modelo preentrenado fue entrenado con muchos datos, el ajuste requerirá menos datos para tener resultados decentes.
* Por la misma razón, la cantidad de tiempo y recursos necesarios para tener buenos resultados es mucho menor.

Por ejemplo, se podría aprovechar un modelo preentrenado en Inglés y después ajustarlo con un corpus arXiv, teniendo como resultado un modelo basado en investigación científica. El ajuste solo requerirá una cantidad limitada de datos: el conocimiento que el modelo preentrenado ha adquirido se "transfiere", de ahí el término *transferencia de aprendizaje*.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/finetuning.svg" alt="The fine-tuning of a language model is cheaper than pretraining in both time and money.">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/finetuning-dark.svg" alt="The fine-tuning of a language model is cheaper than pretraining in both time and money.">
</div>

De ese modo, el ajuste de un modelo tendrá menos costos de tiempo, de datos, financieros y ambientales. Además es más rápido y más fácil de iterar en diferentes esquemas de ajuste, dado que el entrenamiento es menos restrictivo que un preentrenamiento completo.

Este proceso también conseguirá mejores resultados que entrenar desde cero (a menos que tengas una gran cantidad de datos), razón por la cual siempre deberías intentar aprovechar un modelo preentrenado -- uno que esté tan cerca como sea posible a la tarea respectiva -- y ajustarlo.

## Arquitectura general

En esta sección, revisaremos la arquitectura general del Transformador. No te preocupes si no entiendes algunos de los conceptos; hay secciones detalladas más adelante para cada uno de los componentes.

<Youtube id="H39Z_720T5s" />

## Introducción

El modelo está compuesto por dos bloques:

* **Codificador (izquierda)**: El codificador recibe una entrada y construye una representación de ésta (sus características). Esto significa que el modelo está optimizado para conseguir un entendimiento a partir de la entrada.
* **Decodificador (derecha)**: El decodificador usa la representación del codificador (características) junto con otras entradas para generar una secuencia objetivo. Esto significa que el modelo está optimizado para generar salidas.

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_blocks.svg" alt="Architecture of a Transformers models">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers_blocks-dark.svg" alt="Architecture of a Transformers models">
</div>

Cada una de estas partes puede ser usada de manera independiente, dependiendo de la tarea:

* **Modelos con solo codificadores**: Buenos para las tareas que requieren el entendimiento de la entrada, como la clasificación de oraciones y reconocimiento de entidades nombradas.
* **Modelos con solo decodificadores**: Buenos para tareas generativas como la generación de textos.
* **Modelos con codificadores y decodificadores** o **Modelos secuencia a secuencia**: Buenos para tareas generativas que requieren una entrada, como la traducción o resumen.

Vamos a abordar estas arquitecturas de manera independiente en secciones posteriores.

## Capas de atención

Una característica clave de los Transformadores es que están construidos con capas especiales llamadas *capas de atención*. De hecho, el título del trabajo que introdujo la arquitectura de los Transformadores fue ["Attention Is All You Need"](https://arxiv.org/abs/1706.03762). Vamos a explorar los detalles de las capas de atención más adelante en el curso; por ahora, todo lo que tienes que saber es que esta capa va a indicarle al modelo que tiene que prestar especial atención a ciertas partes de la oración que le pasaste (y más o menos ignorar las demás), cuando trabaje con la representación de cada palabra.

Para poner esto en contexto, piensa en la tarea de traducir texto de Inglés a Francés. Dada la entrada "You like this course", un modelo de traducción necesitará tener en cuenta la palabra adyacente "You" para obtener la traducción correcta de la palabra "like", porque en Francés el verbo "like" se conjuga de manera distinta dependiendo del sujeto. Sin embargo, el resto de la oración no es útil para la traducción de esa palabra. En la misma línea, al traducir "this", el modelo también deberá prestar atención a la palabra "course", porque "this" se traduce de manera distinta dependiendo de si el nombre asociado es masculino o femenino. De nuevo, las otras palabras en la oración no van a importar para la traducción de "this". Con oraciones (y reglas gramaticales) más complejas, el modelo deberá prestar especial atención a palabras que pueden aparecer más lejos en la oración para traducir correctamente cada palabra.

El mismo concepto aplica para cualquier tarea asociada con lenguaje natural: una palabra por si misma tiene un significado, pero ese significado está afectado profundamente por el contexto, que puede ser cualquier palabra (o palabras) antes o después de la palabra que está siendo estudiada.

Ahora que tienes una idea de qué son las capas de atención, echemos un vistazo más de cerca a la arquitectura del Transformador.

## La arquitectura original

La arquitectura del Transformador fue diseñada originalmente para traducción. Durante el entrenamiento, el codificador recibe entradas (oraciones) en un idioma dado, mientras que el decodificador recibe las mismas oraciones en el idioma objetivo. En el codificador, las capas de atención pueden usar todas las palabras en una oración (dado que, como vimos, la traducción de una palabra dada puede ser dependiente de lo que está antes y después en la oración). Por su parte, el decodificador trabaja de manera secuencial y sólo le puede prestar atención a las palabras en la oración que ya ha traducido (es decir, sólo las palabras antes de que la palabra se ha generado). Por ejemplo, cuando hemos predicho las primeras tres palabras del objetivo de traducción se las damos al decodificador, que luego usa todas las entradas del codificador para intentar predecir la cuarta palabra.

Para acelerar el entrenamiento (cuando el modelo tiene acceso a las oraciones objetivo), al decodificador se le alimenta el objetivo completo, pero no puede usar palabras futuras (si tuviera acceso a la palabra en la posición 2 cuando trata de predecir la palabra en la posición 2, ¡el problema no sería muy difícil!). Por ejemplo, al intentar predecir la cuarta palabra, la capa de atención sólo tendría acceso a las palabras en las posiciones 1 a 3.

La arquitectura original del Transformador se veía así, con el codificador a la izquierda y el decodificador a la derecha:

<div class="flex justify-center">
<img class="block dark:hidden" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers.svg" alt="Architecture of a Transformers models">
<img class="hidden dark:block" src="https://huggingface.co/datasets/huggingface-course/documentation-images/resolve/main/en/chapter1/transformers-dark.svg" alt="Architecture of a Transformers models">
</div>

Observa que la primera capa de atención en un bloque de decodificador presta atención a todas las entradas (pasadas) al decodificador, mientras que la segunda capa de atención usa la salida del codificador. De esta manera puede acceder a toda la oración de entrada para predecir de mejor manera la palabra actual. Esto es muy útil dado que diferentes idiomas pueden tener reglas gramaticales que ponen las palabras en orden distinto o algún contexto que se provee después puede ser útil para determinar la mejor traducción de una palabra dada.

La *máscara de atención* también se puede usar en el codificador/decodificador para evitar que el modelo preste atención a algunas palabras especiales --por ejemplo, la palabra especial de relleno que hace que todas las entradas sean de la misma longitud cuando se agrupan oraciones.

##  Arquitecturas vs. puntos de control

A medida que estudiemos a profundidad los Transformadores, verás menciones a *arquitecturas*, *puntos de control* (*checkpoints*) y *modelos*. Estos términos tienen significados ligeramente diferentes:

* **Arquitecturas**: Este es el esqueleto del modelo -- la definición de cada capa y cada operación que sucede al interior del modelo.
* **Puntos de control**: Estos son los pesos que serán cargados en una arquitectura dada.
* **Modelo**: Esta es un término sombrilla que no es tan preciso como "arquitectura" o "punto de control" y puede significar ambas cosas. Este curso especificará *arquitectura* o *punto de control* cuando sea relevante para evitar ambigüedades.

Por ejemplo, mientras que BERT es una arquitectura, `bert-base-cased` - un conjunto de pesos entrenados por el equipo de Google para la primera versión de BERT - es un punto de control. Sin embargo, se podría decir "el modelo BERT" y "el modelo `bert-base-cased`". 
